<?php

global $auth;

class Auth extends App {
	public static $UserInfo;
	public static $Data;
	
	public static function Init () {
		Auth::$UserInfo = &$_SESSION["auth"]["user"];

		if (conf("auth.method")=='mysql'&&!DB::CheckTable(conf("auth.tbl_roles"))) {
			DB::Query("CREATE TABLE `".conf("auth.tbl_roles")."` (
			`id` INT( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
			`name` VARCHAR( 25 ) NOT NULL ,
			`permissions` TEXT NOT NULL ,
			UNIQUE (`name`)
			) ENGINE = InnoDB;");
		}
		if (conf("auth.method")=='mysql'&&!DB::CheckTable(conf("auth.tbl_users"))) {
			DB::Query("CREATE TABLE `".conf("auth.tbl_users")."` (
			`id` INT( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
			`username` VARCHAR( 50 ) NOT NULL ,
			`password` VARCHAR( 50 ) NOT NULL ,
			`email` VARCHAR( 255 ) NOT NULL ,
			`permissions` TEXT NOT NULL ,
			UNIQUE (`username`)
			) ENGINE = InnoDB;");
		}
		if (!$_SESSION["auth"]["perms"]) self::SetDefaultPerms();
	}
	
	public static function GetPublicUserData ($id, $keys = "*") {
		$allowedkeys = array("username", "email");
		if ($keys=="*") $keys = $allowedkeys;
			else $keys = parse_relaxarray($keys);
		
		foreach ($keys as $n=>$k) {
			if (in_array($k, $allowedkeys))
				$keys[$n] = "`{$k}`";
			else unset($keys[$n]);
		}
		
		$fields = implode(",", $keys);
		$q = "SELECT {$fields} FROM ".conf("auth.tbl_users")." WHERE `id`='".mysql_escape_string($id)."';";
		if (sizeof($keys)==1) return DB::GetOneByQuery($q);
			else return DB::DumpQuery($q, "onerow");
	}
	
	public static function Login ($username, $password) {
		if ($Userinfo = self::CheckPassword($username, $password)) {
			$_SESSION["auth"]["in"] = true;
			$_SESSION["auth"]["user"] = $Userinfo;
			$_SESSION["auth"]["user"]["loggedin_at"] = time();
			self::SetDefaultPerms();
			self::ApplyPerm($Userinfo["permissions"]);
			return true;
		}else{
			return false;
		}
	}
	
	public static function CheckPassword ($username, $password) {
		global $auth;
		if (conf("auth.method")=="mysql") {
			if (conf("auth.hash")=="md5") $passhash = md5($password);
			else $passhash = mysql_escape_string($password);
			
			$s = "SELECT * FROM ".conf("auth.tbl_users")." WHERE username='".mysql_escape_string($username)."' and '{$passhash}' in (password);"; // or: in (password,temp_password)
			
			if (!$r = DB::DumpQuery($s, "onerow")) return false;
			return $r;
		}elseif (conf("auth.method")=="array"){
			if (is_array(self::$Data['users'])) foreach (self::$Data['users'] as $u) if ($u['username']==$username) if ($u['password']==$password) return $u;
			return false;
		}
	}

	
	public static function FetchRole($RoleName) {
		global $auth;
		if (conf("auth.method")=="mysql") {
			$r = DB::DumpQuery("SELECT `permissions` FROM `".conf("auth.tbl_roles")."` WHERE `name` = '".mysql_escape_string($RoleName)."';", "onerow");
			if (!$r) return false;
			return $r['permissions'];
		}elseif (conf("auth.method")=="array") {
			if (!$auth['roles']) return false;
			return $auth['roles'][$RoleName]['permissions'];
		}
	}

	public static function SetUserData($UserID, $Key, $Value, $isInteger = false) {
		if (conf("auth.method")=="mysql")
			return DB::SetItem(conf("auth.tbl_users"), $UserID, $Key, $Value, $isInteger);
	}
	
	public static function isUser ($username) {
		global $auth;
		if (conf("auth.method")=="mysql") return (sizeof(DB::DumpQuery("SELECT * FROM ".conf("auth.tbl_users")." WHERE username='".mysql_escape_string($username)."';"))>0) ? true : false;
		elseif (conf("auth.method")=="array") return (array_subkey_match($auth['users'], "username", $username)) ? true : false;
	}
	
	public static function FetchUserData($username) {
		global $auth;
		if ((self::Check("users", "fetch", $username))||($_SESSION["auth"]["user"]["username"]==$username)) {
			if (conf("auth.method")=="mysql")
				return DB::DumpQuery("SELECT * FROM ".conf("auth.tbl_users")." WHERE username='".mysql_escape_string($username)."';", "onerow");
			elseif (conf("auth.method")=="array")
				return array_subkey_match($auth['users'], "username", $username);
		}
	}

	public static function ClearPerms() {
		unset($_SESSION["auth"]["perms"]);
	}
	
	public static function ApplyPerm($PermString) {
		$Perms = array_parseconfig($PermString);
		
		foreach ($Perms as $_key => $_value) {
			if ($_key=="role") {
				foreach ($_value as $__key => $__value) {
					self::ApplyPerm(self::FetchRole($__key));
					//$Perms = array_merge_recursive($Perms, self::FetchRole($__key));
					unset($Perms["role"][$__key]);
				}
				unset($Perms["role"]);
			}else{
				if (!$_SESSION["auth"]["perms"][$_key]) $_SESSION["auth"]["perms"][$_key] = array();
				
				foreach ($_value as $__key => $__value)
					foreach ($__value as $_sonunda)
						$_SESSION["auth"]["perms"][$_key][$__key][] = $_sonunda;
			}
		}
		//$_SESSION["perms"] = array_merge_recursive($_SESSION["perms"] ? $_SESSION["perms"] : array(), $Perms);
	}

	public static function SetDefaultPerms() {
		self::ClearPerms();
		self::ApplyPerm(self::FetchRole("default"));
	}

	public static function Logout() {
		self::SetDefaultPerms();
		unset ($_SESSION["auth"]);
		return true;
	}
	/**
	 * If no permission name specified, returns true if user logged in, false if else
	 * If a permission name is specified, thens checks current users permissions
	 * 
	 * @param String $PermissionName
	 * @return Boolean
	 */
	public static function Check($Perm = null, $Key = null, $Val = null) {
		if ($Perm == null) {
			if (isset($_SESSION["auth"])) {
				if ((isset($_SESSION["auth"]["in"]))&&($_SESSION["auth"]["in"]))
					return true;
				else
					return false;
			}else{
				return false;
			}
		}else{
			//self::ClearPerms();
			if ((!$_SESSION["auth"]["perms"])&&(!$_SESSION["auth"]["in"]))
				self::SetDefaultPerms();
			
			$Permissions = &$_SESSION["auth"]["perms"];

			if (@in_array("*", $Permissions["*"]["*"]))
				return true;
			if (($Perm) && ($Key) && ($Val))
				return (
							@in_array($Val, $Permissions[$Perm][$Key]) || 
							@in_array($Val, $Permissions[$Perm]["*"]) ||
							@in_array("*", $Permissions[$Perm]["*"])
						)
						? true 
						: false;
			if (($Perm) && ($Key) && is_null($Val))
				return (
							@in_array("*", $Permissions[$Perm][$Key]) ||
							@in_array("*", $Permissions[$Perm]["*"])
						)
						? true 
						: false;
			if (($Perm) && ($Key) && is_null($Val))
				return (@in_array("*", $Permissions[$Perm][$Key])) ? true : false;
			if (($Perm) && is_null($Key) && is_null($Val))
				return (@in_array("*", $Permissions[$Perm]["*"])) ? true : false;
		}
	}
	
	public static function AuthInfo() {
		return $_SESSION["auth"];
	}

	public static function UserCount() {
		global $auth;
		if (conf("auth.method")=="mysql")
			return DB::GetOneByQuery("select count(id) as user_count from ".conf("auth.tbl_users"));
		elseif (conf("auth.method")=="array")
			return sizeof($auth['users']);
	}
	
	public static function ajax__LoginForm () {
		if (!self::Check()) return Ajax::Popup(smarty_render('login.tpl'), 600);
	}
	
	public static function ajax__Login ($username, $password) {
		global $root;
		if (self::Login($username, $password)) {
			Ajax::Script("document.location='$root';");
		}else{
			Ajax::Script("ajax_open_popup('Kullanıcı adı veya şifre yanlış'); setTimeout('ajax_hide_popup();', 2000);");
		}
	}
	
	public static function ajax__Logout() {
		global $root;
		self::Logout();
		Ajax::Script("document.location='$root';");
	}
}

// TO USE IN TEMPLATES
function perm($perm=null,$key=null,$val=null) {
	return Auth::Check($perm,$key,$val);
}

Auth::$Data = $auth;
	
?>
